package com.ldn.basic.utils;

import cn.hutool.core.date.*;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;


/**
 * @author 李大牛家的牛 (scafel@163.com)
 * @createDate 2024/7/11 - 15:45
 * @description ...
 **/
public class DateUtils {

    public static long getCurrentMS() {
        return System.currentTimeMillis();
    }

    public static long getCurrentS() {
        return System.currentTimeMillis() / 1000;
    }

    public static long parseUTC(String time) {
        assert time != null;
        try {
            Date date = DateUtil.parseUTC(time);
            return date.getTime();
        }catch (Exception e) {
            throw new RuntimeException("时间格式不正确" + e.getMessage());
        }
    }

    public static long getTimeInUnixSeconds(long time) {
        final Date minValidDate = DateUtil.parse("2020-01-01");
        try {
            Date date = DateUtil.date(time);
            if (date.before(minValidDate)) {
                throw new RuntimeException("时间格式不正确");
            }
            return date.getTime();
        } catch (Exception e) {
            throw new RuntimeException("时间格式不正确" + e.getMessage());
        }
    }

    public static String getCurrentDate() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }


    /**
     * @author 李大牛家的牛(scafel@163.com)
     * @description 获取当天剩余时间，单位为毫秒
     * @title getLeftMillisTime
     * @date 2024/1/26 - 11:58
     * @return long 剩余时间（以毫秒为单位）
     **/
    public static long getLeftMillisTime() {
        LocalDateTime now = LocalDateTime.now().withNano(0);
        Instant instant = now.atZone(ZoneId.of("UTC")).toInstant();
        return instant.toEpochMilli() - getCurrentMS();
    }

    /**
     * @author 李大牛家的牛(scafel@163.com)
     * @description 获取剩余时间，单位为秒
     * @title getLeftSecondsTime
     * @date 2024/1/26 - 11:59
     * @return long 剩余时间（以秒为单位）
     **/
    public static long getLeftSecondsTime() {
        return getLeftMillisTime() / 1000L;
    }

    public static long getBeginOfDay() {
        Date now = DateUtil.parse(LocalDateTime.now().toString());
        return getBeginOfDay(now);
    }

    public static long getBeginOfDay(long time) {
        Date now = DateUtil.parse(formatDate(time));
        return getBeginOfDay(now);
    }

    public static long getBeginOfDay(Date date) {
        Date beginOfDay = DateUtil.beginOfDay(date);
        return beginOfDay.getTime() / 1000;
    }

    public static long getEndOfDay() {
        Date now = DateUtil.parse(LocalDateTime.now().toString());
        return getEndOfDay(now);
    }

    public static long getEndOfDay(long time) {
        Date now = DateUtil.parse(formatDate(time));
        return getEndOfDay(now);
    }
    public static long getEndOfDay(Date date) {
        Date beginOfDay = DateUtil.endOfDay(date);
        return beginOfDay.getTime() / 1000;
    }

    public static long getBeginOfMonth() {
        Date now = DateUtil.parse(LocalDateTime.now().toString());
        return getBeginOfMonth(now);
    }

    public static long getBeginOfMonth(long time) {
        Date now = DateUtil.parse(formatDate(time));
        return getBeginOfMonth(now);
    }

    public static long getBeginOfMonth(Date date) {
        Date beginOfMonth = DateUtil.beginOfMonth(date);
        return beginOfMonth.getTime() / 1000;
    }

    public static long getEndOfMonth() {
        Date now = DateUtil.parse(LocalDateTime.now().toString());
        return getEndOfMonth(now);
    }

    public static long getEndOfMonth(long time) {
        Date now = DateUtil.parse(formatDate(time));
        return getEndOfMonth(now);
    }

    public static long getEndOfMonth(Date date) {
        Date endOfMonth = DateUtil.endOfMonth(date);
        return endOfMonth.getTime() / 1000;
    }

    // 获取据今天多长天
    public static long getNumberForNow(long time) {
        return getNumberForNow(time,  DateUnit.DAY);
    }

    public static long getNumberForNow(long time, DateUnit dateUnit) {
        String times = (time +"0000000000000000").substring(0,13);
        Date date = DateUtil.parse(times);
        return DateUtil.between(new Date(), date, dateUnit, false);
    }

    /**
     * @author 李大牛家的牛(scafel@163.com)
     * @description 获取当前天干地支时间
     * @title getCyclicalYMD
     * @date 2024/1/26 - 14:18
     * @return java.lang.String 获取当前天干地支时间 格式 庚子年甲申月癸卯日
     **/
    public static String getCyclicalYMD() {
        Date now = DateUtil.parse(LocalDateTime.now().toString());
        return getCyclicalYMD(now);
    }

    public static String getCyclicalYMD(Date date) {
        //通过公历构建
        ChineseDate chineseDate = new ChineseDate(date);
        return chineseDate.getCyclicalYMD();
    }

    /**
     * @author 李大牛家的牛(scafel@163.com)
     * @description 获取当前时间的天干和生肖
     * @title getDateBorn
     * @date 2024/1/26 - 14:25
     * @return java.lang.String
     **/
    public static String getDateBorn() {
        Date now = DateUtil.parse(LocalDateTime.now().toString());
        return getDateBorn(now);
    }

    public static String getDateBorn(Date date) {
        ChineseDate chineseDate = new ChineseDate(date);
        // 庚子
        String cy = chineseDate.getCyclical();
        // 生肖：鼠
        String cs = chineseDate.getChineseZodiac();
        return cy + cs;
    }

    public static String formatDate(long time) {
        return formatDate(time, "yyyy年MM月dd日 HH:mm:ss");
    }

    public static String formatDate(long time, String format) {
        String times = (time +"0000000000000000").substring(0,13);
        DateTime date = DateUtil.date(Long.parseLong(times));
        return DateUtil.format(date, format);
    }

    public static String getLocalDate(String format) {
        return DateUtil.format(new Date(), format);
    }
    public static String getLocalDate() {
        return getLocalDate("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
    }

    public static String onlyOnceCron(long time) {
        return formatDate(time, "ss mm HH dd MM ? yyyy");
    }

    public static long getTimeOffset(long time, int offset, DateField dateField) {
        Date date = DateUtil.parse(formatDate(time));
        Date newDate = DateUtil.offset(date, dateField, offset);
        return newDate.getTime() / 1000;
    }

    public static long getTimeOffset(long time, int offset) {
        return getTimeOffset(time, offset, DateField.DAY_OF_YEAR);
    }

    public static long getTimeOffset(int offset) {
        long time = getCurrentS();
        return getTimeOffset(time, offset, DateField.DAY_OF_YEAR);
    }
}
